/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package microlensing;

import javalens.util.CalculationException;
import simple.*;
import algorithm.BreedingSelector;
import algorithm.Environment;
import algorithm.ObjectiveFunction;
import algorithm.PopulationBreeder;
import algorithm.PopulationInitializer;
import java.util.ArrayList;
import java.util.List;
import javalens.astronomy.Event;
import javalens.astronomy.LightCurve;
import junit.framework.TestCase;

/**
 *
 * @author Pierre
 */
public class RunMicrolensingGA extends TestCase {

    public void testSimpleMicrolensingGA() throws CalculationException {
        final int nGenerations = 100;
        double mutationChance = 0.05;
        double mutationFraction = 0.05;
        int populationSize = 100;
        int nParameters = 7;
        int nBitsPerParameter = 16;
        
        PopulationInitializer initializer = new BitStringPopulationInitializer(populationSize, nParameters * nBitsPerParameter);
        BreedingSelector selector = new RankRouletteWheelSelector();
        PopulationBreeder crossOverBreeder = new DefaultPopulationBreeder(
                selector,
                new CrossOverOperator());
        PopulationBreeder mutator = new MutationBreeder(mutationChance, mutationFraction);
        
        double b = 0.9;
        double te = 12;
        double tm = 4;
        double m0 = 21;
        double a = 1.2;
        double ang = 90;
        double q = 0.1;
        Event eventToFit = new Event(b,te,tm,m0);
        eventToFit.setA(a);
        eventToFit.setAng(ang);
        eventToFit.setQ(q);
        LightCurve toFitCurve = LightCurve.createRegularTimeCurve(-35, 70, 300, eventToFit);
        ObjectiveFunction obj = new BinaryLensFitObjectiveFunction(toFitCurve);

        Event minEvent = new Event(0.5,3,-10,18);
        minEvent.setA(0.2);
        minEvent.setAng(30);
        minEvent.setQ(.001);

        Event maxEvent = new Event(2,25,15,22);
        minEvent.setA(3);
        minEvent.setAng(180);
        minEvent.setQ(1);


        Event startEvent = new Event(2,10,10,20.5);
        minEvent.setA(.8);
        minEvent.setAng(45);
        minEvent.setQ(0.5);

        List<String> toFit = new ArrayList<String>();
        toFit.add("a");
        toFit.add("ang");
        toFit.add("b");
        toFit.add("m0");
        toFit.add("q");
        toFit.add("te");
        toFit.add("tm");

        Environment environment = new Environment(obj,new MicrolensEventBitStringEncoder(minEvent, maxEvent, startEvent, toFit, nBitsPerParameter, nParameters));
        
        SimpleGeneticAlgorithm algo = new SimpleGeneticAlgorithm(
                initializer,
                new NumberOfGenerationsStopCriterion(nGenerations),
                crossOverBreeder,
                mutator,
                environment);
        algo.addGenerationReport(new LogGenerationReport());
        try {
            algo.run();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
